package com.zxy.ziems.server.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zxy.btp.common.exception.ConditionException;
import com.zxy.btp.common.response.PageResult;
import com.zxy.btp.common.util.JsonUtils;
import com.zxy.ziems.server.constant.PointDataType;
import com.zxy.ziems.server.constant.enums.PointStatusEnum;
import com.zxy.ziems.server.convert.ChannelEquipConvert;
import com.zxy.ziems.server.convert.EquipPointRelConvert;
import com.zxy.ziems.server.convert.PointConvert;
import com.zxy.ziems.server.domain.ChannelEquip;
import com.zxy.ziems.server.domain.EquipPointRel;
import com.zxy.ziems.server.domain.FieldValue;
import com.zxy.ziems.server.domain.Point;
import com.zxy.ziems.server.domain.User;
import com.zxy.ziems.server.dto.EquipPointRelDto;
import com.zxy.ziems.server.dto.PointQueryDto;
import com.zxy.ziems.server.mapper.EquipPointRelMapper;
import com.zxy.ziems.server.mapper.PointMapper;
import com.zxy.ziems.server.service.EquipPointRelService;
import com.zxy.ziems.server.service.FieldValueService;
import com.zxy.ziems.server.service.UserService;
import com.zxy.ziems.server.vo.ChannelEquipVo;
import com.zxy.ziems.server.vo.EquipPointRelVo;
import com.zxy.ziems.server.vo.FieldValueVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName EquipPointRelServiceImpl
 * @Description
 * @Author 邓伟
 * @Date 2023/11/30 14:18
 * @Version 1.0
 */
@Service
public class EquipPointRelServiceImpl extends ServiceImpl<EquipPointRelMapper, EquipPointRel> implements EquipPointRelService {

    @Autowired
    private EquipPointRelMapper equipPointRelMapper;
    @Autowired
    private PointMapper pointMapper;
    @Autowired
    private FieldValueService fieldValueService;

    @Autowired
    private UserService userService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addOrUpdate(EquipPointRelDto equipPointRelDto) {
        checkCodeAndName(equipPointRelDto);
        String pointId = equipPointRelDto.getPointId();
        EquipPointRel equipPointRel = EquipPointRelConvert.INSTANCE.equipPointRelDtoToEquipPointRel(equipPointRelDto);
        Point point = new Point();
        point.setPointCode(equipPointRelDto.getPointCode());
        point.setPointName(equipPointRelDto.getPointName());
        point.setDataFrom(equipPointRelDto.getChannelName());
        if (StrUtil.isEmpty(pointId)) {
            point.setDataObtainType(PointDataType.AUTO);
            point.setPointStatus(PointStatusEnum.START.code());
            pointMapper.insert(point);
            equipPointRel.setPointId(point.getPointId());
            equipPointRelMapper.insert(equipPointRel);
        }else {
            point.setPointId(pointId);
            pointMapper.updateById(point);
            //根据点位id更新关联表数据
            QueryWrapper<EquipPointRel> query = new QueryWrapper<>();
            query.lambda().eq(EquipPointRel::getPointId,pointId);
            equipPointRelMapper.update(equipPointRel,query);
        }
        //更新参数信息
        fieldValueService.batchInsert(equipPointRelDto.getChannelId(),point.getPointId(),point.getPointCode(),equipPointRelDto.getFieldValueDtoList());

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String pointId) {
        //删除点位
        pointMapper.deleteById(pointId);
        //删除设备点位关联数据
        QueryWrapper<EquipPointRel> query = new QueryWrapper<>();
        query.lambda().eq(EquipPointRel::getPointId,pointId);
        equipPointRelMapper.delete(query);
        //删除参数信息
        QueryWrapper<FieldValue> queryRel = new QueryWrapper<>();
        queryRel.lambda().eq(FieldValue::getDataId,pointId);
        fieldValueService.remove(queryRel);
    }

    @Override
    public EquipPointRelVo detail(String pointId) {
        //查询详情
        QueryWrapper<EquipPointRel> query = new QueryWrapper<>();
        query.lambda().eq(EquipPointRel::getPointId,pointId);
        EquipPointRel equipPointRel = equipPointRelMapper.selectOne(query);
        EquipPointRelVo equipPointRelVo = EquipPointRelConvert.INSTANCE.equipPointRelToEquipPointRelVo(equipPointRel);
        //查询点位名称
        Point point = pointMapper.selectById(pointId);
        equipPointRelVo.setPointName(point.getPointName());
        //查询参数信息
        List<FieldValueVo> fieldValueVoList = fieldValueService.selectList(List.of(pointId));
        equipPointRelVo.setParamList(fieldValueVoList);
        return equipPointRelVo;
    }

    @Override
    public PageResult<EquipPointRelVo> pageList(PointQueryDto pointQueryDto) {
        //组装wrapper
        Page<EquipPointRelVo> page = equipPointRelMapper.selectPageList(new Page<>(pointQueryDto.getPageNo(), pointQueryDto.getPageSize()),pointQueryDto);
        List<EquipPointRelVo> records = page.getRecords();
        //空值
        if (ObjectUtil.isEmpty(records)){
            return new PageResult<>(page.getTotal(), Collections.emptyList());
        }
        List<String> userIdList = records.stream().map(EquipPointRelVo::getUpdateUserId).toList();
        //负责人
        Map<String,String> userMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(userIdList)){
            List<User> userList = userService.listByIds(userIdList);
            userMap = userList.stream().collect(Collectors.toMap(User::getUserId,User::getUserName));
        }
        //查询参数信息
        List<String> pointIdList = records.stream().map(EquipPointRelVo::getPointId).toList();
        List<FieldValueVo> channelFieldList = fieldValueService.selectList(pointIdList);
        Map<String, Map<String, String>> map = channelFieldList.stream().collect(Collectors.groupingBy(FieldValueVo::getDataId, Collectors.toMap(FieldValueVo::getFieldName, FieldValueVo::getFieldValue)));
        List<EquipPointRelVo> voList = new ArrayList<>();
        for (EquipPointRelVo equipPointRelVo : records) {
            equipPointRelVo.setUpdateUserName(userMap.get(equipPointRelVo.getUpdateUserId()));
            //处理参数
            Map<String, String> paramMap = map.get(equipPointRelVo.getPointId());
            equipPointRelVo.setParamStr(JsonUtils.toJSONString(paramMap));

            voList.add(equipPointRelVo);
        }
        return new PageResult<>(page.getTotal(),voList);
    }

    private void checkCodeAndName(EquipPointRelDto equipPointRelDto) {
        String pointId = equipPointRelDto.getPointId();
        QueryWrapper<Point> queryCode = new QueryWrapper<>();
        queryCode.lambda().eq(Point::getPointCode,equipPointRelDto.getPointCode());
        if (StrUtil.isNotEmpty(pointId)) {
            queryCode.lambda().ne(Point::getPointId,pointId);
        }
        Long countCode = pointMapper.selectCount(queryCode);
        if (countCode > 0 ) {
            throw new ConditionException("点位编码不能重复");
        }
        queryCode.clear();
        queryCode.lambda().eq(Point::getPointName,equipPointRelDto.getPointName());
        if (StrUtil.isNotEmpty(pointId)) {
            queryCode.lambda().ne(Point::getPointId,pointId);
        }
        Long countName = pointMapper.selectCount(queryCode);
        if (countName > 0 ) {
            throw new ConditionException("点位名称不能重复");
        }

    }
}
